import FirstTitle from "@/components/FirstTitle";
import SubTitle from "@/components/subTitle";
import EffectContainer from "@/components/effectContainer";

import style from "./index.module.scss";
import { useEffect, useRef, useState } from "react";
import { getCode } from "@/api/codeApi.ts";
import Code from "@/components/code";
export const RequestAnimationFrameComp = () => {
  const [code, setCode] = useState("");
  const [code1, setCode1] = useState("");
  const [code2, setCode2] = useState("");
  useEffect(() => {
    getCode("/requestAnimationFrame/递归调用示例.txt").then(({ data }) => {
      setCode(data);
    });
    getCode("/requestAnimationFrame/示例1.txt").then(({ data }) => {
      setCode1(data);
    });
    getCode("/requestAnimationFrame/示例2.txt").then(({ data }) => {
      setCode2(data);
    });
  }, []);

  let rafId: any = null;
  let angle = 0;
  const [boxStyle, setBoxStyle] = useState("rotate(0deg)");
  const animate = (time: number) => {
    // const angle = (time % 1000) / 5;
    angle++;
    if (angle >= 360) angle = 0;
    setBoxStyle(`rotate(${angle}deg)`);
    rafId = window.requestAnimationFrame(animate);
  };
  useEffect(() => {
    rafId = window.requestAnimationFrame(animate);
    return () => {
      if (rafId) {
        window.cancelAnimationFrame(rafId);
      }
    };
  }, []);

  let rafSId: any = null;
  const [list, setList] = useState<string[]>([]);
  const [isLoading, setIsLoading] = useState(false);
  const scrollRef = useRef<HTMLUListElement>(null);
  const getData = () => {
    setIsLoading(true);
    return new Promise<void>((resolve) => {
      setTimeout(() => {
        setList([
          ...list,
          ...Array.from({ length: 50 }, (_, index) => `li=>${index}`),
        ]);
        setIsLoading(false);
        resolve();
      }, 1000);
    });
  };
  const handlerScroll = () => {
    if (rafSId !== null) {
      window.cancelAnimationFrame(rafSId);
    }
    rafSId = window.requestAnimationFrame(checkScrollPosition);
  };
  // 检查是否需要加载数据
  const checkScrollPosition = () => {
    if (isLoading) return;
    if (scrollRef.current) {
      const scrollTop = scrollRef.current.scrollTop;
      const clientHeight = scrollRef.current.clientHeight;
      const scrollHeight = scrollRef.current.scrollHeight;
      if (scrollHeight - scrollTop - clientHeight <= 30) {
        getData();
      }
    }
  };
  useEffect(() => {
    getData();
    return () => {
      if (rafSId) {
        window.cancelAnimationFrame(rafSId);
      }
    };
  }, []);
  return (
    <>
      <FirstTitle title="requestAnimationFrame" />
      <SubTitle title="requestAnimationFrame作用与用法"></SubTitle>

      <EffectContainer
        effect={
          <>
            <p className={style.text}>
              其实很多人会局限于把
              <code className={style.code}>requestAnimationFrame</code>
              应用于一些纯动画相关的需求上，但其实在前端很多业务场景下
              <code className={style.code}>requestAnimationFrame</code>
              都能用于性能优化，下面将细说一下
              <code className={style.code}>requestAnimationFrame</code>
              的具体用法和几种应用场景
            </p>
            <p className={style.text}>
              <code className={style.code}>window.requestAnimationFrame()</code>
              方法会告诉浏览器你希望执行一个动画.
            </p>
            <p className={style.text}>
              他要求浏览器在下一次重绘之前,调用用户提供的回调函数
              .对于回调函数的调用频率通常与显示器的刷新率相匹配.虽然75hz,120hz和144hz也被广泛使用,但是最常见的刷新率还是
              60hz(每秒60个周期/帧).为了提高性能和电池的寿命,大多数浏览器都会暂停在后台选修卡
              或者隐藏的{"<iframe>"}中运行的
              <code className={style.code}>requestAnimationFrame</code>
            </p>
            <p className={style.text}>
              执行后的回调函数有且只会返回一个参数，并且返回的参数是一个毫秒数，这个参数所表示是的上一帧渲染的结束时间
            </p>
            <p className={style.text}>
              终止此API的执行，官方提供的方法是window.cancelAnimationFrame()，语法如下
              <code className={style.code}>
                cancelAnimationFrame(requestID)
              </code>
            </p>
          </>
        }
        isShowCode={true}
        code={<Code content={code} />}
      />

      <SubTitle title="应用 常规动画"></SubTitle>
      <EffectContainer
        effect={
          <>
            <div style={{ transform: boxStyle }} className={style.box}></div>
          </>
        }
        code={<Code content={code1} />}
      />

      <SubTitle title="应用 滚动加载"></SubTitle>
      <EffectContainer
        effect={
          <ul
            ref={scrollRef}
            onScroll={handlerScroll}
            style={{
              width: "98%",
              padding: "20px",
              margin: "20px 0",
              height: "300px",
              overflow: "auto",
            }}
          >
            {list.map((item) => {
              return (
                <li
                  style={{
                    height: "30px",
                    lineHeight: "30px",
                    borderBottom: "1px solid #ccc",
                  }}
                >
                  {item}
                </li>
              );
            })}
            {isLoading && <div>数据加载中...</div>}
          </ul>
        }
        code={<Code content={code2} />}
      />
    </>
  );
};
